<!DOCTYPE html>
<html lang="en">

<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8">
	<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
	
	<!-- title -->
	
	<title>
	
		NIO | 
	 
	对线面试官
	</title>
	
	<!-- keywords,description -->
	 
		<meta name="description" content="Java一线大厂面试" />
	

	<!-- favicon -->
	
	<link rel="shortcut icon" href="/luffy/favicon.ico">
	


	<!-- search -->
	<script>
		var searchEngine = "https://www.baidu.com/s?wd=";
		if(typeof searchEngine == "undefined" || searchEngine == null || searchEngine == ""){
			searchEngine = "https://www.google.com/search?q=";
		}
		var homeHost = "";
		if(typeof homeHost == "undefined" || homeHost == null || homeHost == ""){
			homeHost = window.location.host;
		}
	</script>


	
<link rel="stylesheet" href="/luffy/css/main.css">

	
<link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css">

	
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.17.1/build/styles/darcula.min.css">

	
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css">


	
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.17.1/build/highlight.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/npm/jquery-pjax@2.0.1/jquery.pjax.min.js"></script>

	
<script src="/luffy/js/main.js"></script>

	
		
<script src="https://cdn.jsdelivr.net/npm/leancloud-storage/dist/av-min.js"></script>

		
<script src="https://cdn.jsdelivr.net/npm/valine@1.3.10/dist/Valine.min.js"></script>

	
	
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
	<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?3efe99c287df5a1d6f0d02d187e403c1";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>

<header id="header">
    <a id="title" target="_blank" rel="noopener" href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzU4NzA3MTc5Mg==&action=getalbum&album_id=1657204970858872832&scene=126#wechat_redirect" class="logo">对线面试官</a>

	<ul id="menu">
		
	

	

		<li class="menu-item">
			<a href="https://gitee.com/zhongfucheng/Java3y" class="menu-item-link" target="_blank">
				【戳这里】获取更多原创干货💪💪
			</a>
		</li>
		<li class="menu-item">
			<a href="https://gitee.com/zhongfucheng/Java3y" class="menu-item-link" target="_blank">
				<i class="fa fa-github fa-2x"></i>
			</a>
		</li>
	</ul>
</header>

	
<div id="sidebar">
	<button id="sidebar-toggle" class="toggle" ><i class="fa fa-arrow-right " aria-hidden="true"></i></button>
	
	<div id="site-toc">
		<input id="search-input" class="search-input" type="search" placeholder="按回车全站搜索">
		<div id="tree">
			

			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										00-面试前准备
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/30/00-%E9%9D%A2%E8%AF%95%E5%89%8D%E5%87%86%E5%A4%87/01.%E7%AE%80%E5%8E%86/">
										01.简历
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										01-Java基础
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/01.%20%E6%B3%A8%E8%A7%A3/">
										01. 注解
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/02.%20%E6%B3%9B%E5%9E%8B/">
										02. 泛型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file active">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/03.%20JavaNIO/">
										03. JavaNIO
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/04.%20%E5%8F%8D%E5%B0%84%E5%92%8C%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/">
										04. 反射和动态代理
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										02-Java并发
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/01.%20%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%9F%BA%E7%A1%80/">
										01. 多线程基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/02.%20CAS/">
										02. CAS
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/03.%20synchronized/">
										03. synchronized
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/04.%20AQS%E5%92%8CReentrantLock/">
										04. AQS和ReentrantLock
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/05.%20%E7%BA%BF%E7%A8%8B%E6%B1%A0/">
										05. 线程池
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/06.%20ThreadLocal/">
										06. ThreadLocal
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/07.%20CountDownLatch%E5%92%8CCyclicBarrier/">
										07. CountDownLatch和CyclicBarrier
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/08.%20%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81Java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/">
										08. 为什么需要Java内存模型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/09.%20%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BAJava%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/">
										09. 深入浅出Java内存模型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										03-Java容器
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/03-Java%E5%AE%B9%E5%99%A8/01.%20List%E9%9B%86%E5%90%88/">
										01. List集合
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/03-Java%E5%AE%B9%E5%99%A8/02.%20Map%E9%9B%86%E5%90%88/">
										02. Map集合
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										04-Java虚拟机
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/01.%20Java%E7%BC%96%E8%AF%91%E5%88%B0%E6%89%A7%E8%A1%8C%E7%9A%84%E8%BF%87%E7%A8%8B/">
										01. Java编译到执行的过程
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/02.%20%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%9C%BA%E5%88%B6/">
										02. 双亲委派机制
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/03.%20JVM%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84/">
										03. JVM内存结构
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/04.%20%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E6%9C%BA%E5%88%B6/">
										04. 垃圾回收机制
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/05.%20CMS%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8/">
										05. CMS垃圾收集器
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/06.%20G1%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8/">
										06. G1垃圾收集器
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/24/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/07.%20JVM%E8%B0%83%E4%BC%98/">
										07. JVM调优
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										05-Spring
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/05-Spring/01.%20SpringMVC/">
										01. SpringMVC
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/05-Spring/02.%20Spring%E5%9F%BA%E7%A1%80/">
										02. Spring基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/05-Spring/03.%20SpringBean%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/">
										03. SpringBean生命周期
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										06-Redis
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/06-Redis/01.%20Redis%E5%9F%BA%E7%A1%80/">
										01. Redis基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/06-Redis/02.%20Redis%E6%8C%81%E4%B9%85%E5%8C%96/">
										02. Redis持久化
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/06-Redis/03.%20Redis%E4%B8%BB%E4%BB%8E%E6%9E%B6%E6%9E%84/">
										03. Redis主从架构
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/06-Redis/04.%20Redis%E5%88%86%E7%89%87%E9%9B%86%E7%BE%A4/">
										04. Redis分片集群
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										07-消息队列
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/07-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/01.%20Kafka%E5%9F%BA%E7%A1%80/">
										01. Kafka基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/07-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/02.%20%E4%BD%BF%E7%94%A8Kafka%E4%BC%9A%E8%80%83%E8%99%91%E4%BB%80%E4%B9%88%E9%97%AE%E9%A2%98/">
										02. 使用Kafka会考虑什么问题
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										08-MySQL
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/01.%20MySQL%E7%B4%A2%E5%BC%95/">
										01. MySQL索引
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/02.%20MySQL%E4%BA%8B%E5%8A%A1%E5%92%8C%E9%94%81%E6%9C%BA%E5%88%B6%E5%92%8CMVCC/">
										02. MySQL事务和锁机制和MVCC
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/03.%20MySQL%E8%B0%83%E4%BC%98/">
										03. MySQL调优
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										09-项目场景类
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/01.%20%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E5%8E%BB%E9%87%8D%E5%92%8C%E5%B9%82%E7%AD%89/">
										01. 如何实现去重和幂等
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/02.%20%E7%B3%BB%E7%BB%9F%E9%9C%80%E6%B1%82%E5%A4%9A%E5%8F%98%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1/">
										02. 系统需求多变如何设计
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/03.%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">
										03. 设计模式
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										10-计算机网络
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/25/10-%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/01.%20HTTP/">
										01. HTTP
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/13/10-%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/02.TCP%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E5%92%8C%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/">
										02.TCP三次握手和四次挥手
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										11-算法
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/01/11-%E7%AE%97%E6%B3%95/01.%20%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/">
										01. 排序算法
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/02/11-%E7%AE%97%E6%B3%95/02.%20LeetCode%20Easy/">
										02. LeetCode Easy
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/02/11-%E7%AE%97%E6%B3%95/02.%20LeetCode%20Medium/">
										02. LeetCode Medium
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										12-austin项目
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/01/12-austin%E9%A1%B9%E7%9B%AE/00.%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D/">
										00.项目介绍
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/30/12-austin%E9%A1%B9%E7%9B%AE/01.%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/">
										01.环境搭建
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/30/12-austin%E9%A1%B9%E7%9B%AE/02.%E6%97%A5%E5%BF%97/">
										02.日志
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/03.%E5%B7%A5%E5%85%B7%E5%8C%85/">
										03.工具包
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/04.%E4%BB%8E%E4%B8%80%E6%9D%A1%E7%9F%AD%E4%BF%A1%E5%BC%80%E5%A7%8B/">
										04.从一条短信开始
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/05.%E9%80%89%E6%8B%A9%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E6%8A%80%E6%9C%AF%E9%80%89%E5%9E%8B/">
										05.选择数据库和技术选型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/06.MySQL%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/">
										06.MySQL环境搭建
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/07.Kafka%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/">
										07.Kafka环境搭建
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
		</div>
	</div>
</div>

	<!-- 引入正文 -->
	<div id="content">
		<h1 id="article-title">

	03. JavaNIO
</h1>
<div class="article-meta">
	
	<span>3y</span>
	<span>2021-08-19 10:39:15</span>
		<div id="article-categories">
    
		<span>Categories：</span>
            
    

    
		<span>Tags：</span>
            
    
		</div>

</div>

<div id="article-content">
	<p><span style="color:#ab4642"><strong>面试官</strong></span>：这次咱们就来聊聊Java 的NIO呗？<strong>你对NIO有多少了解？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：嗯，我对Java NIO还是有一定的了解的，NIO是JDK 1.4 开始有的，其目的是为了提高速度。NIO翻译成 no-blocking io 或者 new io 都无所谓啦，反正都说得通</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>你先来讲讲NIO和传统IO有什么区别吧</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：传统IO是一次一个字节地处理数据，NIO是以块（缓冲区）的形式处理数据。最主要的是，NIO可以实现非阻塞，而传统IO只能是阻塞的。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：IO的实际场景是文件IO和网络IO，NIO在网络IO场景下提升就尤其明显了。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在Java NIO有三个核心部分组成。分别是Buffer（缓冲区）、Channel（管道）以及Selector（选择器）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：可以简单的理解为：Buffer是存储数据的地方，Channel是运输数据的载体，而Selector用于检查多个Channel的状态变更情况，</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我曾经写过一个NIO Demo，<span style="color:#ab4642"><strong>面试官</strong></span>可以看看。</p>
<pre><code class="java">public class NoBlockServer &#123;

    public static void main(String[] args) throws IOException &#123;

        // 1.获取通道
        ServerSocketChannel server = ServerSocketChannel.open();

        // 2.切换成非阻塞模式
        server.configureBlocking(false);

        // 3. 绑定连接
        server.bind(new InetSocketAddress(6666));

        // 4. 获取选择器
        Selector selector = Selector.open();

        // 4.1将通道注册到选择器上，指定接收“监听通道”事件
        server.register(selector, SelectionKey.OP_ACCEPT);

        // 5. 轮训地获取选择器上已“就绪”的事件---&gt;只要select()&gt;0，说明已就绪
        while (selector.select() &gt; 0) &#123;
            // 6. 获取当前选择器所有注册的“选择键”(已就绪的监听事件)
            Iterator&lt;SelectionKey&gt; iterator = selector.selectedKeys().iterator();

            // 7. 获取已“就绪”的事件，(不同的事件做不同的事)
            while (iterator.hasNext()) &#123;

                SelectionKey selectionKey = iterator.next();

                // 接收事件就绪
                if (selectionKey.isAcceptable()) &#123;

                    // 8. 获取客户端的链接
                    SocketChannel client = server.accept();

                    // 8.1 切换成非阻塞状态
                    client.configureBlocking(false);

                    // 8.2 注册到选择器上--&gt;拿到客户端的连接为了读取通道的数据(监听读就绪事件)
                    client.register(selector, SelectionKey.OP_READ);

                &#125; else if (selectionKey.isReadable()) &#123; // 读事件就绪

                    // 9. 获取当前选择器读就绪状态的通道
                    SocketChannel client = (SocketChannel) selectionKey.channel();

                    // 9.1读取数据
                    ByteBuffer buffer = ByteBuffer.allocate(1024);

                    // 9.2得到文件通道，将客户端传递过来的图片写到本地项目下(写模式、没有则创建)
                    FileChannel outChannel = FileChannel.open(Paths.get(&quot;2.png&quot;), StandardOpenOption.WRITE, StandardOpenOption.CREATE);

                    while (client.read(buffer) &gt; 0) &#123;
                        // 在读之前都要切换成读模式
                        buffer.flip();

                        outChannel.write(buffer);

                        // 读完切换成写模式，能让管道继续读取文件的数据
                        buffer.clear();
                    &#125;
                &#125;
                // 10. 取消选择键(已经处理过的事件，就应该取消掉了)
                iterator.remove();
            &#125;
        &#125;

    &#125;
&#125;
</code></pre>
<pre><code class="java">public class NoBlockClient &#123;

    public static void main(String[] args) throws IOException &#123;

        // 1. 获取通道
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(&quot;127.0.0.1&quot;, 6666));

        // 1.1切换成非阻塞模式
        socketChannel.configureBlocking(false);

        // 1.2获取选择器
        Selector selector = Selector.open();

        // 1.3将通道注册到选择器中，获取服务端返回的数据
        socketChannel.register(selector, SelectionKey.OP_READ);

        // 2. 发送一张图片给服务端吧
        FileChannel fileChannel = FileChannel.open(Paths.get(&quot;X:\\Users\\ozc\\Desktop\\面试造火箭\\1.png&quot;), StandardOpenOption.READ);

        // 3.要使用NIO，有了Channel，就必然要有Buffer，Buffer是与数据打交道的呢
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        // 4.读取本地文件(图片)，发送到服务器
        while (fileChannel.read(buffer) != -1) &#123;

            // 在读之前都要切换成读模式
            buffer.flip();

            socketChannel.write(buffer);

            // 读完切换成写模式，能让管道继续读取文件的数据
            buffer.clear();
        &#125;


        // 5. 轮训地获取选择器上已“就绪”的事件---&gt;只要select()&gt;0，说明已就绪
        while (selector.select() &gt; 0) &#123;
            // 6. 获取当前选择器所有注册的“选择键”(已就绪的监听事件)
            Iterator&lt;SelectionKey&gt; iterator = selector.selectedKeys().iterator();

            // 7. 获取已“就绪”的事件，(不同的事件做不同的事)
            while (iterator.hasNext()) &#123;

                SelectionKey selectionKey = iterator.next();

                // 8. 读事件就绪
                if (selectionKey.isReadable()) &#123;

                    // 8.1得到对应的通道
                    SocketChannel channel = (SocketChannel) selectionKey.channel();

                    ByteBuffer responseBuffer = ByteBuffer.allocate(1024);

                    // 9. 知道服务端要返回响应的数据给客户端，客户端在这里接收
                    int readBytes = channel.read(responseBuffer);

                    if (readBytes &gt; 0) &#123;
                        // 切换读模式
                        responseBuffer.flip();
                        System.out.println(new String(responseBuffer.array(), 0, readBytes));
                    &#125;
                &#125;

                // 10. 取消选择键(已经处理过的事件，就应该取消掉了)
                iterator.remove();
            &#125;
        &#125;
    &#125;

&#125;
</code></pre>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：这都是些API相关的知识，能看得出来你有一定的基础</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>你知道IO模型有几种吗</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在Unix下IO模型分别有：阻塞IO、非阻塞IO、IO复用、信号驱动以及异步I/O。在开发中碰得最多的就是阻塞IO、非阻塞IO以及IO复用。</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>嗯，来重点讲讲IO复用模型吧</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我就以Linux系统为例好了，我们都知道Linux对文件的操作实际上就是通过文件描述符(fd)</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：IO复用模型指的就是：通过一个进程监听多个文件描述符，一旦某个文件描述符准备就绪，就去通知程序做相对应的处理</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：这种以通知的方式，优势并不是对于单个连接能处理得更快，而是在于它能处理更多的连接。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在Linux下IO复用模型用的函数有select/poll和epoll</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>那你来讲讲这select和epoll函数的区别呗？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：嗯，先说select吧。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：select函数它支持最大的连接数是1024或2048，因为在select函数下要传入fd_set参数，这个fd_set的大小要么1024或2048（其实就看操作系统的位数）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：fd_set就是bitmap的数据结构，可以简单理解为只要位为0，那说明还没数据到缓冲区，只要位为1，那说明数据已经到缓冲区。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：而select函数做的就是每次将fd_set遍历，判断标志位有没有发现变化，如果有变化则通知程序做中断处理。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：epoll 是在Linux2.6内核正式提出，完善了select 的一些缺点。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：它定义了epoll_event结构体来处理，不存在最大连接数的限制。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：并且它不像select函数每次把所有的文件描述符(fd)都遍历，简单理解就是epoll把就绪的文件描述符(fd)专门维护了一块空间，每次从就绪列表里边拿就好了，不再进行对所有文件描述符(fd)进行遍历。</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtszsbrhvwj616k09smyc02.jpg"></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯。<strong>你知道什么叫做零拷贝吗？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：知道的。我们以读操作为例，假设用户程序发起一次读请求。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：其实会调用read相关的「系统函数」，然后会从用户态切换到内核态，随后CPU会告诉DMA去磁盘把数据拷贝到内核空间。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：等到「内核缓冲区」真正有数据之后，CPU会把「内核缓存区」数据拷贝到「用户缓冲区」，最终用户程序才能获取到。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：稍微解释一下：为了保证内核的安全，操心系统将虚拟空间划分为「用户空间」和「内核空间」，所以在读系统数据的时候会有状态切换</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtszty9haej60q009274z02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：因为应用程序不能直接去读取硬盘的数据，从上面描述可知需要依赖「内核缓冲区」</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：一次读操作会让DMA将磁盘数据拷贝到内核缓冲区，CPU将内核缓冲区数据拷贝到用户缓冲区。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：所谓的零拷贝就是将「CPU将内核缓冲区数据拷贝到用户缓冲区」这次CPU拷贝给省去，来提高效率和性能</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：常见的零拷贝技术有mmap（内核缓冲区与用户缓冲区的共享）、sendfile（系统底层函数支持）。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：零拷贝可以提高数据传输的性能，这块在Kafka等框架也有相关的实践。</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtt04u807kj614m0r077a02.jpg"></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯，了解了</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtlxsqby50j61400qpdkz02.jpg"></p>
<p><span align="center">第一时间获取<span style="color:#000080"><strong>BATJTMD一线互联网大厂</strong></span>最新的面试资料以及内推机会关注公众号<span style="color:#ab4642"><strong>「对线<span style="color:#ab4642"><strong>面试官</strong></span>」</strong></span></p>
<img align="center" src='https://tva1.sinaimg.cn/large/008i3skNgy1gtlvty8zo5j60u00u0q5602.jpg' width=300px height=300px />




</div>


    <div class="post-guide">
        <div class="item left">
            
              <a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/04.%20%E5%8F%8D%E5%B0%84%E5%92%8C%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/">
                  <i class="fa fa-angle-left" aria-hidden="true"></i>
                  04. 反射和动态代理
              </a>
            
        </div>
        <div class="item right">
            
              <a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/02.%20%E6%B3%9B%E5%9E%8B/">
                02. 泛型
                <i class="fa fa-angle-right" aria-hidden="true"></i>
              </a>
            
        </div>
    </div>




<script>
	
	
</script>
	</div>
	<button id="totop-toggle" class="toggle"><i class="fa fa-angle-double-up" aria-hidden="true"></i></button>
</body>
</html>
